﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using PI_CS_Library;
using PI_CS_Library.Virtual_Network_Information_Model;
using PI_CS_Library.PicsNetwork_Information_Model;

namespace PI_CS_GUI
{
    public partial class PicsNCGUI : Form
    {

        private  PI_CS_Library.PicsNetworkController _picsNC;
        private  PI_CS_Library.PicsServer _server;
        public event GUIDelegate _formsAction;
        private bool AUTOSAVE;
        private int EDGE = 662;

        public PicsNCGUI()
        {

            _picsNC = new  PI_CS_Library.PicsNetworkController();

            InitializeComponent();

            cb.Text = "Autosave ";
            cb.BackColor = Color.Transparent;
            cb.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
            cb.Enabled = false;
            ToolStripControlHost host = new ToolStripControlHost(cb);
            host.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
            topologyToolStripMenuItem.DropDownItems.Insert(2, host);


            AUTOSAVE = false;
            _formsAction += new GUIDelegate(FormsControl);
            networkViewer1.GUI = _formsAction;

            networkViewer1.VNOperators = _picsNC.VNOperators;
            
        }

        private void TopologyLoad(string _filename)
        {
            if (_picsNC.InitiateTopology(_filename))
            {
                ShowPhysicalNetwork();
                networkViewer1.ManagerEngine = _picsNC.ManagerEngine;
                _server = new PI_CS_Library.PicsServer(_picsNC, _formsAction);
           
            }
        }

        private void ShowPhysicalNetwork()
        {
            networkViewer1.Refresh(_picsNC.Network);
            _formsAction(null, new GUIArgs("showPhysicalTopology"));
        }
        
        private void ShowVirtualNetwork()
        {
            VirtualNetwork _currVN = (VirtualNetwork)listBox2.SelectedItem;
            networkViewer1.Refresh(_currVN);

            _formsAction(null, new GUIArgs("showVirtualTopology#"+_currVN));
        }

        private void ShowFileBrowser(object sender, EventArgs e)
        {
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK) 
            {
                string file = openFileDialog1.FileName;
                TopologyLoad(file);
            }
            _formsAction(null, new GUIArgs("loadTopologyOK"));
  	    
	    
        }

        public void FormsControl(object oSender, EventArgs oEventArgs)
        {
            string _src, _dst;
            int _vnId;

            if (this.InvokeRequired)
                this.Invoke(new GUIDelegate(this.FormsControl), oSender, oEventArgs);
            else
            {
                GUIArgs oGUIArgs = oEventArgs as GUIArgs;

                string[] param = oGUIArgs._content.Split('#');

                switch (param[0])
                {
                    case "newVNO":
                        listBox1.Enabled = true;
                        listBox1.Items.Add(_picsNC.GetVNO(Int32.Parse(param[1])));
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - Connection accepted - VNO: " + _picsNC.GetVNO(Int32.Parse(param[1])).Login + "\n");
                        break;

                    case "newVirtualNetwork":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - " + param[1] + " adds new virtual network: " + param[2] + " - OK \n"); 
                        break;

                    case "removeVirtualNetwork":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - " + param[1] + " removes virtual network: " + param[2] + " - OK \n");
                        break;

                    case "newVirtualLink":
                        _vnId = Int32.Parse(param[2]);
                        if (listBox2.SelectedItem!=null)
                            if (((VirtualNetwork)listBox2.SelectedItem).Id.Number == _vnId)
                                networkViewer1.Refresh(_picsNC.Network.GetVirtualNetwork(_vnId));
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - "+ param[1] + " adds new virtual link: " + param[3] + " -> " + param[4] + 
                            " to virtual network: "+param[2]+ " - OK \n"); 
                        break;

                    case "removeVirtualLink":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - " + param[1] + " removes virtual link: " + param[3] + " - "+  param[4] +
                            " -> "+param[5]+" from virtual network: "+param[2]+" - OK \n");
                        break;

                    case "newVirtualLinkFailed":
                        networkViewer1.Refresh(_picsNC.Network.GetVirtualNetwork(Int32.Parse(param[2])));
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - VNO: " + param[1] + " adds new virtual link: " + param[3] + " -> " + param[4] +
                            " to virtual network: " + param[2] + "  - Failed \n"); 
                        break;

                    case "newMatrixOK":
                        networkViewer1.Refresh(_picsNC.Network);
                        pictureBox4.BorderStyle = BorderStyle.None;
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - New data plane matrix added: " + param[1] + "\n");
                        PicsMatrix _newMatrix = _picsNC.Network.GetMatrix(_picsNC.Network.GetMatrixId(param[1]));
                        _server.BroadcastMessage("Update Add " + _newMatrix.Id.Number + ":" + _newMatrix.Name + ":" + 
                            _newMatrix.Type + ":" + _newMatrix.PositionX + ":" + _newMatrix.PositionY);
                        if (AUTOSAVE) Save();
                        break;

                    case "newMatrixCancel":
                        pictureBox4.BorderStyle = BorderStyle.None;
                        break;

                    case "newLinkOK":
                        networkViewer1.Refresh(_picsNC.Network);
                        _src = _picsNC.Network.GetLink(Int32.Parse(param[1])).SrcMatrix.Name;
                        _dst = _picsNC.Network.GetLink(Int32.Parse(param[1])).SinkMatrix.Name;
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - New data plane link added: " +_src + " -> "+ _dst + " - " + param[1] + "\n");
                        pictureBox6.BorderStyle = BorderStyle.None;
                        if (AUTOSAVE) Save();
                        break;

                    case "delLinkOK":
                        if (param[4] == "refresh") networkViewer1.Refresh(_picsNC.Network);
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - Data plane link deleted: " + param[1] + " -> " + param[2] + " - " + param[3] + "\n");
                        pictureBox7.BorderStyle = BorderStyle.None;
                        if (AUTOSAVE) Save();
                        break;

                    case "delLinkCancel":
                        pictureBox7.BorderStyle = BorderStyle.None;
                        break;

                    case "delMatrixOK":
                        if (param[2] == "refresh") networkViewer1.Refresh(_picsNC.Network);
                        pictureBox5.BorderStyle = BorderStyle.None;
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - Data plane matrix removed: " + param[1] + "\n");
                        _server.BroadcastMessage("Update Remove " + _picsNC.Network.GetMatrixId(param[1]));
                        if (AUTOSAVE) Save();
                        break;

                    case "delMatrixCancel":
                        pictureBox5.BorderStyle = BorderStyle.None;
                        break;

                    case "linkDown":
                        int _picsLinkId = Int32.Parse(param[1]);
                        _vnId = _picsNC.Network.GetVirtualLink(_picsLinkId).vnId;
                        int _linkId = _picsNC.Network.GetVirtualLink(_picsLinkId).LinkId;
                        int _srcMatrixId = _picsNC.Network.GetVirtualNetwork(_vnId).GetLink(_linkId).SrcMatrix.Id.Number;
                        int _sinkMatrixId = _picsNC.Network.GetVirtualNetwork(_vnId).GetLink(_linkId).SinkMatrix.Id.Number;
                        int _vnoId = _picsNC.Network.GetVirtualNetwork(_vnId).VnoId.Number;
                        _server.Send(_server.VNODirectory[_vnoId], "link_down " + _vnId + " " + _srcMatrixId + " " + _sinkMatrixId);
                        break;

                    case "showPhysicalTopology":
                        label4.Text = "Data plane network";
                        label4.Font = new Font(label4.Font.FontFamily.Name, 12);
                        label4.Font = new Font(label4.Font, FontStyle.Bold);
                        label4.Location = new Point(EDGE - label4.Size.Width, label4.Location.Y);
                        label4.BackColor = Color.Crimson;
                        break;

                    case "showVirtualTopology":
                        label4.Text = "Virtual network: " + param[1];
                        label4.Font = new Font(label4.Font.FontFamily.Name, 10);
                        label4.Font = new Font(label4.Font, FontStyle.Bold);
                        label4.Location = new Point(EDGE - label4.Size.Width, label4.Location.Y);
                        label4.BackColor = Color.CornflowerBlue;
                        break;

                    case "showVirtualLink":
                        networkViewer1.ShowVirtualLink(Int32.Parse(param[1]));
                        //_picsNC.RemoveVirtualLink(Int32.Parse(param[2]), Int32.Parse(param[1]), true);
                        break;

                    case "loadTopologyOK":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - Network configuration loaded: " + _picsNC.ConfigFile + "\n");
                        ShowComponents();
                        pictureBox1.BorderStyle = BorderStyle.None;
                        break;

                    case "SaveOK":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - Network configuration saved: " + _picsNC.ConfigFile + "\n");
                        pictureBox2.BorderStyle = BorderStyle.None;
                        break;

                    case "logout":
                        richTextBox1.AppendText(DateTime.Now.ToString("G") + " - VNO: " + param[1] + " disconnected "+"\n");
                        listBox1.Items.Remove(param[1]);
                        break;
                }
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBox2.Enabled = true;
            listBox2.Items.Clear();

            VirtualNetworkOperatorInfo _currVNO = (VirtualNetworkOperatorInfo) listBox1.SelectedItem;

            foreach (VirtualNetwork vn in _currVNO.Networks.Values)
            {
                listBox2.Items.Add(vn);
            }

        }

        private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (cb.Checked)
                AUTOSAVE = true;
            else
                AUTOSAVE = false;
        }

        public void Save()
        {
            Serial.SerializeObject(_picsNC.ConfigFile, _picsNC.Network.GetTransportRepresentation());
            _formsAction(this, new GUIArgs("SaveOK"));
        }

        private void elementHost1_ChildChanged(object sender, System.Windows.Forms.Integration.ChildChangedEventArgs e)
        {

        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            ShowVirtualNetwork();
        }

        private void PicsNCGUI_FormClosed(object sender, FormClosedEventArgs e)
        {
            _picsNC.ManagerEngine.Clean();
            
            
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            networkViewer1.Refresh(_picsNC.Network);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void addNewMatrixToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddMatrixGUI _getMatrix = new AddMatrixGUI(_picsNC, _formsAction);
            _getMatrix.ShowDialog(this);
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DelMatrixGUI _delMatrix = new DelMatrixGUI(_picsNC, _formsAction);

            _delMatrix.ShowDialog(this);
        }

        private void addLinkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddLinkGUI _addLink = new AddLinkGUI(_picsNC, _formsAction);

            _addLink.ShowDialog(this);
        }

        private void networkToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void deleteLinkToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox2_MouseHover(object sender, EventArgs e)
        {
            pictureBox2.Cursor = Cursors.Hand;
        }

        private void pictureBox1_MouseHover(object sender, EventArgs e)
        {
            pictureBox1.Cursor = Cursors.Hand;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            pictureBox1.BorderStyle = BorderStyle.Fixed3D;
            ShowFileBrowser(null, null);
        }

        private void pictureBox2_Click_1(object sender, EventArgs e)
        {
            pictureBox2.BorderStyle = BorderStyle.Fixed3D;
            Save();

        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {
            pictureBox3.BorderStyle = BorderStyle.Fixed3D;
            ShowPhysicalNetwork();
            pictureBox3.BorderStyle = BorderStyle.None;
        }

        private void pictureBox3_MouseHover(object sender, EventArgs e)
        {
            pictureBox3.Cursor = Cursors.Hand;
        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {
            pictureBox4.BorderStyle = BorderStyle.Fixed3D;
            AddMatrixGUI _getMatrix = new AddMatrixGUI(_picsNC, _formsAction);
            _getMatrix.ShowDialog(this);
        }

        private void pictureBox4_MouseHover(object sender, EventArgs e)
        {
            pictureBox4.Cursor = Cursors.Hand;
        }

        private void pictureBox6_Click(object sender, EventArgs e)
        {
            pictureBox6.BorderStyle = BorderStyle.Fixed3D;

            AddLinkGUI _addLink = new AddLinkGUI(_picsNC, _formsAction);

            _addLink.ShowDialog(this);
        }

        private void pictureBox7_Click(object sender, EventArgs e)
        {

            pictureBox7.BorderStyle = BorderStyle.Fixed3D;
            DelLinkGUI _delLink = new DelLinkGUI(_picsNC, _formsAction);

            _delLink.ShowDialog();
        }

        private void pictureBox6_MouseHover(object sender, EventArgs e)
        {
            pictureBox6.Cursor = Cursors.Hand;
        }

        private void pictureBox7_MouseHover(object sender, EventArgs e)
        {
            pictureBox7.Cursor = Cursors.Hand;
        }

        private void pictureBox5_Click(object sender, EventArgs e)
        {
            pictureBox5.BorderStyle = BorderStyle.Fixed3D;

            DelMatrixGUI _delMatrix = new DelMatrixGUI(_picsNC, _formsAction);

            _delMatrix.ShowDialog(this);
        }

        private void pictureBox5_MouseHover(object sender, EventArgs e)
        {
            pictureBox5.Cursor = Cursors.Hand;
        }

        private void pictureBox8_Click(object sender, EventArgs e)
        {
            ShowFileBrowser(null, null);
        }

        private void ShowComponents()
        {
            networkToolStripMenuItem.Enabled = true;
            cb.Enabled = true;
            toolStripMenuItem1.Enabled = true;
            optionsToolStripMenuItem.Enabled = true;
            pictureBox8.Visible = false;
            elementHost1.Visible = true;
            pictureBox1.Visible = true;
            pictureBox2.Visible = true;
            pictureBox3.Visible = true;
            pictureBox4.Visible = true;
            pictureBox5.Visible = true;
            pictureBox6.Visible = true;
            pictureBox7.Visible = true;
            pictureBox9.Visible = true;
        }

        private void pictureBox8_MouseHover(object sender, EventArgs e)
        {
            pictureBox8.Cursor = Cursors.Hand;
        }

        private void pictureBox9_MouseHover(object sender, EventArgs e)
        {
            pictureBox9.Cursor = Cursors.Hand;
        }

        private void pictureBox9_Click(object sender, EventArgs e)
        {
            networkViewer1.Refresh();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Parallel Internet Channel Swotching \n Network Controller 1.0", "About");
        }

        private void PicsNCGUI_FormClosed_1(object sender, FormClosedEventArgs e)
        {
            _picsNC.ManagerEngine.Clean();
        }

        private void parametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ParametersGUI _parameters = new ParametersGUI(_picsNC.RC, _formsAction);
            _parameters.ShowDialog(this);
        }





    }
}
